package com.achunt.justtype

import android.Manifest
import android.content.pm.PackageManager

import android.util.Log
import android.content.Context
import android.content.ContentUris
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.inputmethod.InputMethodManager
import android.view.inputmethod.EditorInfo
import android.view.KeyEvent
import android.widget.EditText
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.accessibilityservice.AccessibilityService
import kotlinx.coroutines.*
import java.util.Timer
import java.util.TimerTask
import java.io.InputStream
import com.achunt.justtype.ActionService
//import com.achunt.justtype.OnSwipeTouchListener
import android.provider.Settings
import android.content.*

fun openAccessibilitySettings(context: Context) {
    val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
    val cs = ComponentName(context.packageName, ActionService::class.java.name).flattenToString()
    val bundle = Bundle()
    bundle.putString(":settings:fragment_args_key", cs)
    intent.apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        putExtra(":settings:fragment_args_key", cs)
        putExtra(":settings:show_fragment_args", bundle)
    }
    context.startActivity(intent)
}

  class JustType : androidx.fragment.app.Fragment(),
    androidx.appcompat.widget.SearchView.OnQueryTextListener,
    View.OnClickListener, View.OnLongClickListener {

    lateinit var recyclerView: RecyclerView
    private lateinit var layoutManager: RecyclerView.LayoutManager
    lateinit var jt: EditText
    lateinit var wallpaper: ViewGroup
    lateinit var jtAdapter: JTAdapter
    lateinit var cAdapter: ContactsAdapter
    lateinit var searchRecyclerView: RecyclerView
    lateinit var searchAdapter: SearchAdapter
    lateinit var contactsRecyclerView: RecyclerView
    private lateinit var gDetector : GestureDetector
    private lateinit var touchListener : View.OnTouchListener
    var qSearch: MutableList<String> = MutableList(4) { "web" }
    private var b = true

    @Volatile
    var contactName = ""

    @Volatile
    var contactNumber = ""

    @Volatile
    var cNameTest: ArrayList<String?> = ArrayList()

    @Volatile
    var cNumberTest: ArrayList<String?> = ArrayList()

    @Volatile
    var cUriTest: ArrayList<Uri?> = ArrayList()

    @Volatile
    var cName: ArrayList<String> = ArrayList()
    @Volatile
    var cNumber: ArrayList<String> = ArrayList()
    @Volatile
    var cUri: ArrayList<Uri> = ArrayList()

    val PROJECTION = arrayOf(
        ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.NUMBER,
        ContactsContract.Contacts.PHOTO_THUMBNAIL_URI
    )

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.justtype_search, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        jt = view.findViewById(R.id.jtInput)
        val context = this.requireContext()
        runBlocking {
            val job = this.launch { contactsSearch() }
            job.join()
            jtAdapter = JTAdapter(jt, requireContext(), jt.text.toString())
            searchAdapter = SearchAdapter(jt, qSearch)
        }
        recyclerView = view.findViewById(R.id.justtype_view)
        layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        recyclerView.layoutManager = layoutManager
        recyclerView.visibility = View.INVISIBLE
        recyclerView.adapter = jtAdapter

        val searchLayoutManager = LinearLayoutManager(context)
        searchRecyclerView = view.findViewById(R.id.justtype_search)
        searchRecyclerView.layoutManager = searchLayoutManager
        searchRecyclerView.visibility = View.INVISIBLE
        searchRecyclerView.adapter = searchAdapter

        contactsRecyclerView = view.findViewById(R.id.justtype_contacts)
        layoutManager = LinearLayoutManager(context)
        contactsRecyclerView.layoutManager = layoutManager
        contactsRecyclerView.visibility = View.INVISIBLE
        contactsRecyclerView.adapter = cAdapter

        wallpaper = view.findViewById(R.id.touchArea)
        wallpaper.visibility = View.VISIBLE

        val w: Window = requireActivity().window
        w.statusBarColor = ContextCompat.getColor(requireActivity(), R.color.status)

        jt.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable) {
                if (jt.text.toString().isNotEmpty()) {
                        if(jt.text.toString() == "nn") {
                          if(context != null)
                            expandNotificationDrawer(context as Context)
                            refresh()
                        }
                        b = true
                        for (i in 0..3) {
                            qSearch.add(i, s.toString())
                        }
                        onQueryTextChange(s.toString())
                        contactsRecyclerView.visibility = View.VISIBLE
                        searchRecyclerView.visibility = View.VISIBLE
                        recyclerView.visibility = View.VISIBLE
                        wallpaper.visibility = View.INVISIBLE
                } else {
                    recyclerView.visibility = View.INVISIBLE
                    searchRecyclerView.visibility = View.INVISIBLE
                    contactsRecyclerView.visibility = View.INVISIBLE
                    wallpaper.visibility = View.VISIBLE
                }
            }
        })

        jt.setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
          if(jtAdapter.selectFirst(recyclerView)) {
          } else if(cAdapter.selectFirst(contactsRecyclerView)) {
          } else {
            val url = "https://duckduckgo.com/?q=${jt.text.toString()}"
            val i = Intent(Intent.ACTION_VIEW)
            i.data = Uri.parse(url)
            searchRecyclerView.context.startActivity(i)
          }
          jt.setText("")
        }
        true
      }


        gDetector = GestureDetector(
                      context,
                      MyGestureListener()
                    )

        touchListener = object : View.OnTouchListener, MyGestureListener() {
            override fun onTouch(view: View?, event: MotionEvent): Boolean {
                gDetector.onTouchEvent(event)
                gDetector.setOnDoubleTapListener(this)

                return true
            }

            override fun onDoubleTap(e: MotionEvent): Boolean {
                val actionService = ActionService.instance()
                if (actionService != null) {
                    actionService.lockScreen()
                } else {
                    openAccessibilitySettings(requireContext())
                }
                return true
            }

            override fun onScroll(e1: MotionEvent?, e2: MotionEvent, vx: Float, vy: Float): Boolean {
              Log.d("stuff", "GOT FLUNG")
              return true;
            }

            override fun onFling(e1: MotionEvent?, e2: MotionEvent, vx: Float, vy: Float): Boolean {
              Log.d("stuff", "GOT FLUNG")
              return true;
            }
        }

        wallpaper.setOnTouchListener(getGestureListener(context));

        val timer = Timer()

        timer.schedule(object : TimerTask() {
          override fun run() {
          jt = view.findViewById(R.id.jtInput)
          jt.requestFocus()
          jt.isFocusableInTouchMode
          jt.isFocusable = true
          if (jt.requestFocus()) {
              val imm =
                  view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.showSoftInput(jt, InputMethodManager.SHOW_IMPLICIT)
          }
          timer.cancel()
          }
        }, 0L, 100L)
    }

    override fun onClick(view: View) {
//          super.onClick(view)
//       return true
    }

    override fun onLongClick(view: View): Boolean {
//         super.onLongClick(view)
        return true
    }

    private fun getGestureListener(context: Context): View.OnTouchListener {
        return object : OnSwipeTouchListener(context) {
            override fun onSwipeLeft() {
                val launchIntent = context.packageManager.getLaunchIntentForPackage(
                  "foundation.e.camera"
                )
                context.startActivity(launchIntent)
                super.onSwipeLeft()
            }

            override fun onSwipeRight() {
                val launchIntent = context.packageManager.getLaunchIntentForPackage(
                  "net.gsantner.markor"
                )
                context.startActivity(launchIntent)
                super.onSwipeRight()
            }

            override fun onSwipeUp() {
                val launchIntent = context.packageManager.getLaunchIntentForPackage(
                  "com.android.deskclock"
                )
                context.startActivity(launchIntent)
                super.onSwipeUp()
            }

            override fun onSwipeDown() {
                expandNotificationDrawer(context)
                super.onSwipeDown()
            }

            override fun onLongClick() {
                Log.d("KEV TEST", "long click")
                super.onLongClick()
            }
        }
    }

    open class MyGestureListener : GestureDetector.SimpleOnGestureListener() {
        override fun onDown(event: MotionEvent): Boolean {
            Log.d("KEV TEST", "onDown: " + event.toString());
            return true;
        }

        override fun onFling(event1: MotionEvent? , event2: MotionEvent,
                velocityX: Float, velocityY: Float): Boolean {
            Log.d("KEV TEST", "onFling: " + event1.toString()+event2.toString());
            return true;
        }

        override fun onScroll(event1: MotionEvent? , event2: MotionEvent,
                velocityX: Float, velocityY: Float): Boolean {
            Log.d("KEV TEST", "onScroll: " + event1.toString()+event2.toString());
            return true;
        }

    }
    fun expandNotificationDrawer(context: Context) {
        try {
          val statusBarService = context.getSystemService("statusbar")
          val statusBarManager = Class.forName("android.app.StatusBarManager")
          val method = statusBarManager.getMethod("expandNotificationsPanel")
          method.invoke(statusBarService)
        } catch (e: Exception) {
          e.printStackTrace()
        }
    }

    private fun contactsSearch() {
        val cr = this.requireContext().contentResolver
        val phones: Cursor? = cr
            .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC")
        var idColumn: Int
        var lookupColumn: Int
        var contactUri: Uri?
        var i = 0
        if (phones != null) {
            try {
            while (phones.moveToNext()) {
                contactName =
                    phones.getString(phones.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME) shr 0)
                contactNumber =
                    phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) shr 0)
                idColumn = phones.getColumnIndex(ContactsContract.Contacts._ID)
                lookupColumn = phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)
                contactUri = ContactsContract.Contacts.getLookupUri(
                    phones.getLong(idColumn),
                    phones.getString(lookupColumn)
                )
                if (i > 0) {
                    if (!cNameTest[i - 1]?.contains(contactName)!!) {
                        cNameTest.add(i, contactName)
                        cNumberTest.add(i, contactNumber)
                        cUriTest.add(i, contactUri)
                        i++
                    }
                } else {
                    cNameTest.add(i, contactName)
                    cNumberTest.add(i, contactNumber)
                    cUriTest.add(i, contactUri)
                    i++
                }
            }
          } finally {
            phones?.close()
          }
        }
        cName = cNameTest as ArrayList<String>
        cNumber = cNumberTest as ArrayList<String>
        cUri = cUriTest as ArrayList<Uri>
        contactNumber = ""
        contactName = ""
        phones?.close()
        cAdapter = ContactsAdapter(jt, cr, cName, cNumber, cUri)
    }

    override fun onQueryTextSubmit(query: String): Boolean {
        cAdapter.filter.filter(query)
        jtAdapter.filter.filter(query)
        searchAdapter.filter.filter(query)
        return true
    }

    override fun onQueryTextChange(newText: String): Boolean {
        cAdapter.filter.filter(newText)
        jtAdapter.filter.filter(newText)
        searchAdapter.filter.filter(newText)
        return true
    }

    companion object {
        var textSend = ""
    }

    public fun refresh() {
        jt.setText("")
    }
}
